/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.web.controller;

import com.paypal.ipn.IPNMessage;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.cx1.model.Featured;
import org.cx1.model.Listing;
import org.cx1.model.Transaction;
import org.cx1.model.utils.ServiceResponse;
import org.cx1.model.utils.SystemProperties;
import org.cx1.service.api.IEmailService;
import org.cx1.service.api.IFeaturedService;
import org.cx1.service.api.IListingService;
import org.cx1.service.api.ITransactionService;
import org.cx1.service.impl.DFeaturedService;
import org.cx1.service.impl.DListingService;
import org.cx1.service.impl.DTransactionService;
import org.cx1.service.impl.MEmailService;
import org.cx1.service.impl.MFeaturedService;
import org.cx1.service.utils.Configuration;
import org.cx1.service.utils.FeaturedTransaction;
import org.cx1.service.utils.ipn.IpnHandler;
import org.cx1.service.utils.ipn.IpnInfo;
import org.cx1.web.controller.action.CartAction;
import org.cx1.web.controller.action.FeaturedAction;
import org.cx1.web.utils.SessionUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.view.RedirectView;

/**
 *
 * @author ECH
 */
public class CartController extends BaseController {
            
    private ITransactionService transactionService = new DTransactionService();
    private IFeaturedService featuredService = new DFeaturedService();
    private IListingService listingService = new DListingService();
    
    private IEmailService emailService = new MEmailService();
    
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    private SimpleDateFormat sdf_utc = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    private SimpleDateFormat sdf_manila = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    private SimpleDateFormat sdf_manila2 = new SimpleDateFormat("MMMM dd, yyyy HH:ss");
    
    public CartController() {
        
    }
    
    protected ModelAndView handleRequestInternal( HttpServletRequest request,
                                                  HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView();
        Map map = new HashMap();        
        
        /*
        String userID = SessionUtils.getUserID(request.getSession());     
        if (StringUtils.isEmpty(userID)) {
            mav.setView(new RedirectView("home.htm"));
            return mav;
        } 
        if (!StringUtils.isEmpty(userID)) {
            map.put("loggedin", true);
        }      
        */
        
        Map<String, Object> parameterMap = new HashMap<String, Object>();
        if (ServletFileUpload.isMultipartContent(request)) {
            parameterMap = this.getMultipartFormParams(request);
        } 
        else {
            parameterMap = this.getFormParams(request);
        }
        
        Map<String, String> formfields = (Map<String, String>) parameterMap.get("formfields");
        int action = StringUtils.isEmpty(formfields.get("a")) ? 0 : Integer.parseInt(formfields.get("a"));
        
        switch (action) {
            case CartAction.SUCCESS_PAGE_GENERIC: {
                successPageGeneric(mav, map, request);
                break;
            }
            case CartAction.PROCESS_PAYMENT: {
                processPayment(mav, map, request);
                break;
            }
            case CartAction.PROCESS_PAYMENT_FAKE: {
                processPaymentFake(mav, map, request);
                break;
            }    
            default : {
                mav.setView( new RedirectView("home.htm") );
                break;
            }
        }  
        
        map.put("host", SystemProperties.SYSTEM_HOST);
        map.put("port", SystemProperties.SYSTEM_PORT);
        map.put("props", this.getSystemProperties());
        mav.addObject("model", map);
        return mav;
    }    
        
    private void successPageGeneric(ModelAndView mav, Map map, HttpServletRequest request) {
        mav.setViewName("cartsuccess");
    }
    
    private void processPaymentFake(ModelAndView mav, Map map, HttpServletRequest request) {
        String s = request.getParameter("s");                
        String transactionID = request.getParameter("transactionID");
        
        if (!StringUtils.isEmpty(s)) {                
            //CX: process order            
            String listingID = "";
            String city = "";
            String term = "";
            Date startDate = null;
            Date endDate = null;
            String strStartDate = null;
            String strEndDate = null;
                                    
            try {
                ServiceResponse<Transaction> response1 = transactionService.read(transactionID);
                Transaction transaction = response1.getResponse();
                
                listingID = transaction.getFeatured_listingID();
                city = transaction.getFeatured_city();
                term = transaction.getFeatured_termType();
                startDate = transaction.getFeatured_startDate();
                endDate = transaction.getFeatured_endDate();
                strStartDate = transaction.getFeatured_strStartDate();
                strEndDate = transaction.getFeatured_strEndDate();
                
                Featured featured = new Featured();
                featured.setListingID(listingID);
                featured.setCity(city);
                featured.setTermType(term); // 1 or 2
                featured.setStartDate(startDate);
                featured.setEndDate(endDate);
                featured.setStrStartDate(strStartDate);
                featured.setStrEndDate(strEndDate);
                
                featuredService.create(featured);                
                
                //CX: notify email
                //StringBuilder transSB = new StringBuilder();
                //transSB.append("transactionType: ").append("Yehey!");
                //emailService.sendNewTransaction("chux18@gmail.com", transSB.toString());
            } 
            catch (Exception ex) {
                StringBuilder sb = new StringBuilder();
                sb.append("listingID: ").append(listingID).append(" ")
                  .append("city: ").append(city).append(" ")
                  .append("term: ").append(term).append(" ");
                        
                emailService.sendExeptionCaught("chux18@gmail.com", "CartController: " + ex.getMessage() + "SB: " + sb.toString());
                ex.printStackTrace();
            }
        }
        //CX: generic payment success page
        mav.setView( new RedirectView("cart.htm?a=9") );
    }
    
    private void processPayment(ModelAndView mav, Map map, HttpServletRequest request) {
        String s = request.getParameter("s");  
        String transactionID = "";
        boolean isIpnVerified = false;
        IpnInfo ipnInfo = null;      
        
        try {            
            //CX: if payment successful
            Map<String,String> configurationMap =  Configuration.getConfig();
            IPNMessage ipnlistener = new IPNMessage(request, configurationMap);
            isIpnVerified = ipnlistener.validate();
            String transactionType = ipnlistener.getTransactionType();
            Map<String,String> ipnMap = ipnlistener.getIpnMap();
            
            transactionID = ipnMap.get("custom");
                       
            //CX: email-debug
            String requestURI = request.getRequestURI();
            String queryString = request.getQueryString();            
            StringBuffer sbTest = new StringBuffer();
            sbTest.append("SBTEST ------ ")
                  .append("requestURI: ").append(requestURI).append("\n")
                  .append("queryString: ").append(queryString).append("\n")
                  .append("isIpnVerified: " + isIpnVerified).append("\n")
                  .append("transactionType: " + transactionType).append("\n")
                  .append("ipnMap-transID: " + ipnMap.get("transID")).append("\n")
                  .append("ipnMap-custom: " + ipnMap.get("custom")).append("\n")
                  .append("request-transID: " + request.getParameter("transID"));            
            emailService.sendNewTransaction("chux18@gmail.com", sbTest.toString());
        } 
        catch (Exception ex) {
            ex.printStackTrace();
        }
        
        /*
        try {
            //CX: email-debug
            emailService.sendNewTransaction("chux18@gmail.com", "about to process using ipn handler");
            
            IpnHandler handler = new IpnHandler();
            ipnInfo = handler.handleIpn(request);
            
            //CX: email-debug
            emailService.sendNewTransaction("chux18@gmail.com", ipnInfo.toString());
            
            if (ipnInfo != null) {
                isIpnVerified = true;
                transactionID = ipnInfo.getCustom();
            }
        }   
        catch (Exception ex) {
            emailService.sendNewTransaction("chux18@gmail.com", "Exception: " + ex.getMessage());
            ex.printStackTrace();
        }
        */
        
        if (isIpnVerified || !StringUtils.isEmpty(transactionID)) {
            String listingID = "";
            String city = "";
            String term = "";
            Date startDate = null;
            Date endDate = null;
            String strStartDate = null;
            String strEndDate = null;
                                       
            try {
                emailService.sendNewTransaction("chux18@gmail.com", "about to process transaction: " + transactionID + " isIpnVerified: " + isIpnVerified);
                
                //CX: query transaction object
                ServiceResponse<Transaction> response1 = transactionService.read(transactionID);
                Transaction transaction = response1.getResponse();
                if (transaction != null) {
                    listingID = transaction.getFeatured_listingID();
                    city = transaction.getFeatured_city();
                    term = transaction.getFeatured_termType();
                    startDate = transaction.getFeatured_startDate();
                    endDate = transaction.getFeatured_endDate();
                    strStartDate = transaction.getFeatured_strStartDate();
                    strEndDate = transaction.getFeatured_strEndDate();

                    //CX: process order     
                    Featured featured = new Featured();
                    featured.setListingID(listingID);
                    featured.setCity(city);
                    featured.setTermType(term); // 1 or 2
                    featured.setStartDate(startDate);
                    featured.setEndDate(endDate);
                    featured.setStrStartDate(strStartDate);
                    featured.setStrEndDate(strEndDate);

                    featuredService.create(featured);

                    //CX: email-debug
                    StringBuilder transSB = new StringBuilder();
                    transSB.append("YEHEY!");
                    emailService.sendNewTransaction("chux18@gmail.com", transSB.toString());   
                    
                    //CX: send email to client
                    sendEmail(listingID, city, term, startDate, endDate);
                }
            } 
            catch (Exception ex) {
                StringBuilder sb = new StringBuilder();
                sb.append("listingID: ").append(listingID).append(" ")
                  .append("city: ").append(city).append(" ")
                  .append("term: ").append(term).append(" ");                        
                emailService.sendExeptionCaught("chux18@gmail.com", "CartController: " + ex.getMessage() + "SB: " + sb.toString());
                ex.printStackTrace();
            }
        }
        //CX: generic payment success page
        mav.setView( new RedirectView("cart.htm?a=9") );
    }
        
    private void sendEmail(String listingID, String city, String term, Date startDate, Date endDate) {
        try {            
            String listingTitle = "";
            String name = "";
            String toEmail = "";
            String displayCity = "";
            String rentalTerm = ""; 
            String strStartDate = "";
            String strEndDate = "";
            String url  = "";

            Listing listing = listingService.read(listingID).getResponse();
            if (listing != null) {
                listingTitle = listing.getTitle();

                if (listing.getCreator() != null) {
                    toEmail = listing.getCreator().getEmail();
                    name = listing.getCreator().getFirstName();
                }

                displayCity = city.trim().toLowerCase().substring(0, 1).toUpperCase() + city.substring(1);
                rentalTerm = StringUtils.equalsIgnoreCase(term, "1") ? "long term rentals" : "short term rentals";

                sdf_manila2.setTimeZone(TimeZone.getTimeZone("Asia/Hong_Kong"));
                strStartDate = sdf_manila2.format(startDate);
                strEndDate = sdf_manila2.format(endDate);

                String urlCity = city.trim().toLowerCase().replaceAll(" ", "-");
                String urlTerm = StringUtils.equalsIgnoreCase(term, "1") ? "long-term-rentals" : "short-term-rentals";

                url = "http://rentpad.com.ph/" + urlTerm + "/" + urlCity;

                emailService.sendPropertyFeaturedActive(listingTitle, name, toEmail, city, rentalTerm, strStartDate, strEndDate, url);
            }
        } catch (Exception ex) { }
    }
    
    public static void main (String[] argv) {
        
        CartController cart = new CartController();
        
        Date startDate = new Date();        
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, 7);        
        c.add(Calendar.HOUR, 1);             
        Date endDate = c.getTime();  
        
        cart.sendEmail("6226af1186", "Makati", "1", startDate, endDate);
    }
}